package com.ylzinfo.channelclient.utils;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonGenerationException;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.ylzinfo.channelclient.exception.AppBizException;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.TimeZone;

/**
 * @author zengjw
 * jackson工具类
 */
@Slf4j
public class JsonUtils {
    private static final ObjectMapper OBJECT_MAPPER;
    private static final XmlMapper XML_MAPPER;
    private static final String XML_HEADER = "<?xml version=\"1.0\" encoding=\"GB2312\"?>";
    private static final String XML_HEADER_FWZX = "<?xml version=\"1.0\" encoding=\"GB2312\"?>\r\n";

    static {
        OBJECT_MAPPER = new ObjectMapper();
//        XmlFactory xmlFactory = new XmlFactory(new WstxInputFactory(), new WstxOutputFactory());
//        XML_MAPPER = new XmlMapper(xmlFactory);
        XML_MAPPER = new XmlMapper();
        XML_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);
//        XML_MAPPER = new XmlMapper();
        //去掉默认的时间戳格式
        OBJECT_MAPPER.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
        //设置为中国上海时区
        OBJECT_MAPPER.setTimeZone(TimeZone.getTimeZone("GMT+8"));

        OBJECT_MAPPER.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
        //空值不序列化
        OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        //反序列化时，属性不存在的兼容处理
        OBJECT_MAPPER.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        //序列化时，日期的统一格式
        OBJECT_MAPPER.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));

        OBJECT_MAPPER.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        //单引号处理
        OBJECT_MAPPER.configure(com.fasterxml.jackson.core.JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
    }

    public static <T> T toObject(String json, Class<T> clazz) {
        try {
            return OBJECT_MAPPER.readValue(json, clazz);
        } catch (JsonParseException e) {
            log.info(e.getMessage(), e);
        } catch (JsonMappingException e) {
            log.info(e.getMessage(), e);
        } catch (IOException e) {
            log.info(e.getMessage(), e);
        }
        return null;
    }

    public static <T> String toJson(T entity) {
        try {
            return OBJECT_MAPPER.writeValueAsString(entity);
        } catch (JsonGenerationException e) {
            log.info(e.getMessage(), e);
        } catch (JsonMappingException e) {
            log.info(e.getMessage(), e);
        } catch (IOException e) {
            log.info(e.getMessage(), e);
        }
        return null;
    }

    public static <T> T toCollection(String json, TypeReference<T> typeReference) {
        try {
            return OBJECT_MAPPER.readValue(json, typeReference);
        } catch (JsonParseException e) {
            log.info(e.getMessage(), e);
        } catch (JsonMappingException e) {
            log.info(e.getMessage(), e);
        } catch (IOException e) {
            log.info(e.getMessage(), e);
        }
        return null;
    }

    /**
     * xml转Object
     *
     * @param xml
     * @param classzz
     * @param <T>
     * @return
     * @throws IOException
     */
    public static <T> T xmlToBean(String xml, Class<T> classzz) throws IOException {
        if (xml.startsWith(XML_HEADER)) {
            xml = xml.substring(XML_HEADER.length());
        }
        T obj = XML_MAPPER.readValue(xml, classzz);
        return obj;
    }

    public static <T> String beanToXml(T bean) throws AppBizException {
        String string = null;
        try {
            string = XML_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(bean);
        } catch (JsonProcessingException e) {
            throw new AppBizException(e.getMessage());
        }
        string = XML_HEADER + string;

        return string;
    }

    public static <T> String beanToXmlFWZX(T bean) throws AppBizException {
        String string = null;
        try {
            string = XML_MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(bean);
        } catch (JsonProcessingException e) {
            throw new AppBizException(e.getMessage());
        }
        string = XML_HEADER_FWZX + string;

        return string;
    }
    public static <T> List<T> jsonToList(List<Object> jsonArray, Class<T> beanType) {
        try {
            List<T> list = new ArrayList<>();
            for (Object json : jsonArray) {
                String param = JsonUtils.toJson(json);
//                String object= JsonUtils.toObject((String) json, String.class);
                T t = JsonUtils.toObject(param, beanType);
                list.add(t);
            }
            return list;
        } catch (Exception e) {
            log.error("将json数据转换成pojo对象list:", e);
        }
        return null;
    }

    public static void main(String[] args) throws IOException {
//        ObtainRuleXmlResp obtainRuleXmlResp = ObtainRuleXmlResp.builder().iid("aaa").normCode("bbb").normName("ccc").expandNorm("dd").starLevel("1").build();
//        List<ObtainRuleXmlResp> obtainRuleRespList = new ArrayList<>();
//        obtainRuleRespList.add(obtainRuleXmlResp);
//        ObtainRuleListXmlResp obtainRuleListXmlResp = ObtainRuleListXmlResp.builder().rules(obtainRuleRespList).build();
//        ObtainRuleResp resp = ObtainRuleResp.builder()
//                .code("200")
//                .message("成功")
//                .data(obtainRuleListXmlResp)
//                .build();
//        String s = JsonUtils.beanToXml(resp);
//
//        System.out.println(s);
//        ObtainRuleResp resp1 = JsonUtils.xmlToBean(s, ObtainRuleResp.class);
//        System.out.println(JsonUtils.toJson(resp1));

    }


}

